--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
meshchatx/src/backend/lxmf_utils.py a96697b9a554c7ae068fb1b4a2bd19f34f918ce3 (a96697b9) Text, 36.44 KB
T8b949e# SPDX-License-Identifier: 0BSD
Tff7b72import T7ee787base64
Tff7b72import T7ee787json
Tff7b72import T7ee787LXMF
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787telemetry_utils Tff7b72import Te6edf3Telemeter
T8b949e# MeshChatX app extensions (field 16). not used for LXMF-standard reactions.
Te6edf3LXMF_APP_EXTENSIONS_FIELD Tff7b72= T79c0ff16
T8b949e# LXMF reply / reaction field standards (see LXMF.py FIELD_REPLY_* / FIELD_REACTION)
Te6edf3FIELD_REPLY_TO Tff7b72= Tffa657getattrTb4b4b4(Te6edf3LXMFTb4b4b4, Ta5d6ff"Ta5d6ffFIELD_REPLY_TOTa5d6ff"Tb4b4b4, T79c0ff0x30Tb4b4b4)
Te6edf3FIELD_REPLY_QUOTE Tff7b72= Tffa657getattrTb4b4b4(Te6edf3LXMFTb4b4b4, Ta5d6ff"Ta5d6ffFIELD_REPLY_QUOTETa5d6ff"Tb4b4b4, T79c0ff0x31Tb4b4b4)
Te6edf3FIELD_REACTION Tff7b72= Tffa657getattrTb4b4b4(Te6edf3LXMFTb4b4b4, Ta5d6ff"Ta5d6ffFIELD_REACTIONTa5d6ff"Tb4b4b4, T79c0ff0x40Tb4b4b4)
Te6edf3REACTION_TO Tff7b72= Tffa657getattrTb4b4b4(Te6edf3LXMFTb4b4b4, Ta5d6ff"Ta5d6ffREACTION_TOTa5d6ff"Tb4b4b4, T79c0ff0x00Tb4b4b4)
Te6edf3REACTION_CONTENT Tff7b72= Tffa657getattrTb4b4b4(Te6edf3LXMFTb4b4b4, Ta5d6ff"Ta5d6ffREACTION_CONTENTTa5d6ff"Tb4b4b4, T79c0ff0x01Tb4b4b4)
T8b949e# Raw LXMF integer field identifiers used when classifying "user-facing" payloads
Te6edf3LXMF_FILE_ATTACHMENTS_FIELD Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTS
Te6edf3LXMF_IMAGE_FIELD Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE
Te6edf3LXMF_AUDIO_FIELD Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO
Tff7b72def Td2a8ff_lxmf_dict_keyTb4b4b4(Te6edf3dTb4b4b4: Tffa657dictTb4b4b4, Tff7b72*Te6edf3keysTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3key Tff7b72in Te6edf3keysTb4b4b4:
Tff7b72if Te6edf3key Tff7b72in Te6edf3dTb4b4b4:
Tff7b72return Te6edf3dTb4b4b4[Te6edf3keyTb4b4b4]
Tff7b72return Tff7b72None
Tff7b72def Td2a8ff_bytes_to_message_hash_hexTb4b4b4(Te6edf3valueTb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3valueTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3valueTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3valueTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72None
Tff7b72def Td2a8ff_reaction_content_to_emojiTb4b4b4(Te6edf3valueTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3valueTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3value Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff"
Tff7b72return Tffa657strTb4b4b4(Te6edf3valueTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffparse_lxmf_reaction_field_dictTb4b4b4(
Te6edf3reaction_dictTb4b4b4: Tffa657dictTb4b4b4,
Te6edf3source_hash_hexTb4b4b4: Tffa657str Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657dict Tff7b72| Tff7b72NoneTb4b4b4:
T8b949e"""Parse FIELD_REACTION (0x40) dict into normalized reaction metadata."""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3reaction_dictTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3target_raw Tff7b72= Te6edf3_lxmf_dict_keyTb4b4b4(
Te6edf3reaction_dictTb4b4b4,
Te6edf3REACTION_TOTb4b4b4,
T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ff0x00Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3content_raw Tff7b72= Te6edf3_lxmf_dict_keyTb4b4b4(
Te6edf3reaction_dictTb4b4b4,
Te6edf3REACTION_CONTENTTb4b4b4,
T79c0ff1Tb4b4b4,
Ta5d6ff"Ta5d6ff0x01Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_contentTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffemojiTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3reaction_to Tff7b72= Te6edf3_bytes_to_message_hash_hexTb4b4b4(Te6edf3target_rawTb4b4b4)
Tff7b72if Tff7b72not Te6edf3reaction_toTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4: Te6edf3reaction_toTb4b4b4,
Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4: Te6edf3_reaction_content_to_emojiTb4b4b4(Te6edf3content_rawTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4: Te6edf3source_hash_hex Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4,
Tb4b4b4}
Tff7b72def Td2a8ffextract_reaction_from_lxmf_fieldsTb4b4b4(
Te6edf3message_fieldsTb4b4b4: Tffa657dictTb4b4b4,
Tff7b72*Tb4b4b4,
Te6edf3source_hash_hexTb4b4b4: Tffa657str Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4,
Te6edf3parsed_fieldsTb4b4b4: Tffa657dict Tff7b72| Tff7b72None Tff7b72= Tff7b72NoneTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657dict Tff7b72| Tff7b72NoneTb4b4b4:
T8b949e"""Read LXMF FIELD_REACTION (0x40) from raw or parsed message fields."""
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3message_fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3raw_reaction Tff7b72= Te6edf3_lxmf_dict_keyTb4b4b4(
Te6edf3message_fieldsTb4b4b4,
Te6edf3FIELD_REACTIONTb4b4b4,
Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4,
T79c0ff0x40Tb4b4b4,
Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3raw_reactionTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3parsed Tff7b72= Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(Te6edf3raw_reactionTb4b4b4, Te6edf3source_hash_hexTb4b4b4)
Tff7b72if Te6edf3parsedTb4b4b4:
Tff7b72return Te6edf3parsed
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3parsed_fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3reaction Tff7b72= Te6edf3parsed_fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3reactionTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4: Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4: Te6edf3_reaction_content_to_emojiTb4b4b4(
Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_contentTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4: Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsenderTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3source_hash_hexTb4b4b4,
Tb4b4b4}
Te6edf3parsed Tff7b72= Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(Te6edf3reactionTb4b4b4, Te6edf3source_hash_hexTb4b4b4)
Tff7b72if Te6edf3parsedTb4b4b4:
Tff7b72return Te6edf3parsed
Tff7b72return Tff7b72None
Tff7b72def Td2a8ffbuild_lxmf_reaction_fieldTb4b4b4(Te6edf3target_message_hashTb4b4b4: Tffa657strTb4b4b4, Te6edf3emojiTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
Tff7b72return Tb4b4b4{
Te6edf3REACTION_TOTb4b4b4: Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3target_message_hashTb4b4b4)Tb4b4b4,
Te6edf3REACTION_CONTENTTb4b4b4: Tb4b4b4(Te6edf3emoji Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72def Td2a8fflxmf_fields_are_reactionTb4b4b4(Te6edf3lxmf_fieldsTb4b4b4: Tffa657dictTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3lxmf_fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3raw_reaction Tff7b72= Te6edf3_lxmf_dict_keyTb4b4b4(Te6edf3lxmf_fieldsTb4b4b4, Te6edf3FIELD_REACTIONTb4b4b4, Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4, T79c0ff0x40Tb4b4b4)
Tff7b72return Tffa657isinstanceTb4b4b4(Te6edf3raw_reactionTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Tffa657boolTb4b4b4(
Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(Te6edf3raw_reactionTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8ffis_user_facing_lxmf_payloadTb4b4b4(Te6edf3fieldsTb4b4b4, Te6edf3contentTb4b4b4, Te6edf3titleTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""Determine whether an LXMF message represents a user-visible item.
Messages that should NOT raise the notification bell:
- reactions (FIELD_REACTION with no other payload)
- bare telemetry updates with no coordinates, no stream, and no
Sideband location-request command (FIELD_TELEMETRY body-only noise)
- icon-only / appearance-only updates (no body, no attachment)
- empty pings (no content, no title, no attachment)
Location shares (telemetry including location), telemetry streams,
and Sideband commands entries with key 0x01 (location request) ARE
treated as user-facing so the bell and previews stay informative.
The helper is intentionally tolerant: fields may be the rich dict
produced by convert_lxmf_message_to_dict (string keys), the raw
LXMF integer-keyed dict, or a JSON-string from the database.
"""
Tff7b72import T7ee787json Tff7b72as T7ee787_json
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3fields Tff7b72= Te6edf3_jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3fieldsTb4b4b4) Tff7b72if Te6edf3fields Tff7b72else Tb4b4b4{Tb4b4b4}
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4)Tb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffgetTb4b4b4(
Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3raw_reaction Tff7b72= Tb4b4b4(
Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3FIELD_REACTIONTb4b4b4) Tff7b72or Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(T79c0ff0x40Tb4b4b4)
Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3raw_reactionTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(Te6edf3raw_reactionTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Tff7b72def Td2a8ff_has_textTb4b4b4(Te6edf3valueTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3value Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3value Tff7b72= Te6edf3valueTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72return Tffa657boolTb4b4b4(Tffa657strTb4b4b4(Te6edf3valueTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3_has_textTb4b4b4(Te6edf3contentTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3_has_textTb4b4b4(Te6edf3titleTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Te6edf3image Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3imageTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Tb4b4b4(
Te6edf3imageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3imageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3image Tff7b72is Tff7b72None Tff7b72and Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMF_IMAGE_FIELDTb4b4b4) Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72True
Te6edf3audio Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3audioTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Tb4b4b4(
Te6edf3audioTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudio_sizeTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3audioTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudio_bytesTa5d6ff"Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3audio Tff7b72is Tff7b72None Tff7b72and Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMF_AUDIO_FIELDTb4b4b4) Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72True
Te6edf3file_attachments Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3file_attachmentsTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3file_attachmentsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72True
Te6edf3raw_files Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMF_FILE_ATTACHMENTS_FIELDTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3raw_filesTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3raw_filesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72True
Te6edf3telemetry Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetryTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3telemetryTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3loc Tff7b72= Te6edf3telemetryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflocationTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3locTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3locTb4b4b4:
Tff7b72return Tff7b72True
Te6edf3ts Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetry_streamTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3tsTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3tsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72True
Te6edf3commands Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcommandsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3commandsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3cmd Tff7b72in Te6edf3commandsTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cmdTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Ta5d6ff"Ta5d6ff0x01Ta5d6ff" Tff7b72in Te6edf3cmdTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False
Tff7b72def Td2a8ff_reaction_emoji_from_parsed_lxmf_fieldsTb4b4b4(Te6edf3fieldsTb4b4b4: Tffa657dictTb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3reaction Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3reactionTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3emoji Tff7b72= Te6edf3_reaction_content_to_emojiTb4b4b4(Te6edf3reactionTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_contentTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3emoji Tff7b72or Tff7b72None
Te6edf3raw_reaction Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3FIELD_REACTIONTb4b4b4) Tff7b72or Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(T79c0ff0x40Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3raw_reactionTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3parsed Tff7b72= Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(Te6edf3raw_reactionTb4b4b4)
Tff7b72if Te6edf3parsedTb4b4b4:
Tff7b72return Te6edf3parsedTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4) Tff7b72or Tff7b72None
Tff7b72return Tff7b72None
Tff7b72def Td2a8ff_lxmf_sidebar_actor_labelTb4b4b4(
Te6edf3rowTb4b4b4: Tffa657dictTb4b4b4,
Tff7b72*Tb4b4b4,
Te6edf3local_hashTb4b4b4: Tffa657strTb4b4b4,
Te6edf3peer_display_nameTb4b4b4: Tffa657strTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Te6edf3is_incoming Tff7b72= Tffa657boolTb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3is_incomingTb4b4b4:
Tff7b72return Te6edf3peer_display_name Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"
Te6edf3src Tff7b72= Tb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3loc Tff7b72= Tb4b4b4(Te6edf3local_hash Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72return Tb4b4b4(
Ta5d6ff"Ta5d6ffYouTa5d6ff" Tff7b72if Te6edf3src Tff7b72and Te6edf3loc Tff7b72and Te6edf3src Tff7b72== Te6edf3loc Tff7b72else Tb4b4b4(Te6edf3peer_display_name Tff7b72or Ta5d6ff"Ta5d6ffAnonymous PeerTa5d6ff"Tb4b4b4)
Tb4b4b4)
Tff7b72def Td2a8ff_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4: Tffa657dictTb4b4b4, Tff7b72*Te6edf3keysTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72for Te6edf3key Tff7b72in Te6edf3keysTb4b4b4:
Te6edf3value Tff7b72= Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Te6edf3keyTb4b4b4)
Tff7b72if Te6edf3value Tff7b72in Tb4b4b4(T79c0ff1Tb4b4b4, Tff7b72TrueTb4b4b4, Ta5d6ff"Ta5d6ff1Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False
Tff7b72def Td2a8ff_b64_payload_sizeTb4b4b4(Te6edf3b64_bytesTb4b4b4) Tff7b72-Tff7b72> Tffa657intTb4b4b4:
Tff7b72if Tff7b72not Te6edf3b64_bytes Tff7b72or Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3b64_bytesTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return T79c0ff0
Te6edf3size Tff7b72= Tb4b4b4(Tffa657lenTb4b4b4(Te6edf3b64_bytesTb4b4b4) Tff7b72* T79c0ff3Tb4b4b4) Tff7b72/Tff7b72/ T79c0ff4
Tff7b72if Te6edf3b64_bytesTff7b72.Td2a8ffendswithTb4b4b4(Ta5d6ff"Ta5d6ff==Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3size Tff7b72-Tff7b72= T79c0ff2
Tff7b72elif Te6edf3b64_bytesTff7b72.Td2a8ffendswithTb4b4b4(Ta5d6ff"Ta5d6ff=Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3size Tff7b72-Tff7b72= T79c0ff1
Tff7b72return Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3sizeTb4b4b4)
Tff7b72def Td2a8fflxmf_fields_without_attachment_bytesTb4b4b4(Te6edf3fieldsTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
T8b949e"""Return fields with image/audio/file byte payloads removed.
Used for fields_meta storage and conversation-list/thread APIs so
multi-MB base64 blobs are never re-parsed on every load.
"""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{Tb4b4b4}
Te6edf3out Tff7b72= Tffa657dictTb4b4b4(Te6edf3fieldsTb4b4b4)
Te6edf3image Tff7b72= Te6edf3outTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3imageTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3image_size Tff7b72= Te6edf3imageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4) Tff7b72or T79c0ff0
Te6edf3b64_bytes Tff7b72= Te6edf3imageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3image_size Tff7b72and Te6edf3b64_bytesTb4b4b4:
Te6edf3image_size Tff7b72= Te6edf3_b64_payload_sizeTb4b4b4(Te6edf3b64_bytesTb4b4b4)
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Te6edf3imageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4: Te6edf3image_sizeTb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Te6edf3audio Tff7b72= Te6edf3outTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3audioTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3audio_size Tff7b72= Te6edf3audioTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudio_sizeTa5d6ff"Tb4b4b4) Tff7b72or T79c0ff0
Te6edf3b64_bytes Tff7b72= Te6edf3audioTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudio_bytesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3audio_size Tff7b72and Te6edf3b64_bytesTb4b4b4:
Te6edf3audio_size Tff7b72= Te6edf3_b64_payload_sizeTb4b4b4(Te6edf3b64_bytesTb4b4b4)
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffaudio_modeTa5d6ff"Tb4b4b4: Te6edf3audioTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudio_modeTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffaudio_sizeTa5d6ff"Tb4b4b4: Te6edf3audio_sizeTb4b4b4,
Ta5d6ff"Ta5d6ffaudio_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Te6edf3file_attachments Tff7b72= Te6edf3outTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3file_attachmentsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3slim_files Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3item Tff7b72in Te6edf3file_attachmentsTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3itemTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3file_size Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_sizeTa5d6ff"Tb4b4b4) Tff7b72or T79c0ff0
Te6edf3b64_bytes Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_bytesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3file_size Tff7b72and Te6edf3b64_bytesTb4b4b4:
Te6edf3file_size Tff7b72= Te6edf3_b64_payload_sizeTb4b4b4(Te6edf3b64_bytesTb4b4b4)
Te6edf3slim_filesTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fffile_nameTa5d6ff"Tb4b4b4: Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_nameTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fffile_sizeTa5d6ff"Tb4b4b4: Te6edf3file_sizeTb4b4b4,
Ta5d6ff"Ta5d6fffile_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3slim_files
Tff7b72return Te6edf3out
Tff7b72def Td2a8fflxmf_fields_attachment_flagsTb4b4b4(Te6edf3fieldsTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
T8b949e"""Derive cheap boolean flags from a parsed LXMF fields dict."""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_telemetryTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Tb4b4b4}
Te6edf3has_image Tff7b72= Tb4b4b4(
T79c0ff1 Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)Tb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4) Tff7b72else T79c0ff0
Tb4b4b4)
Te6edf3has_audio Tff7b72= Tb4b4b4(
T79c0ff1 Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)Tb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4) Tff7b72else T79c0ff0
Tb4b4b4)
Te6edf3file_attachments Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4)
Te6edf3has_files Tff7b72= Tb4b4b4(
T79c0ff1 Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3file_attachmentsTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3file_attachmentsTb4b4b4) Tff7b72> T79c0ff0 Tff7b72else T79c0ff0
Tb4b4b4)
Te6edf3has_reaction Tff7b72= T79c0ff1 Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4)Tb4b4b4, Tffa657dictTb4b4b4) Tff7b72else T79c0ff0
Te6edf3has_telemetry Tff7b72= T79c0ff0
Te6edf3telemetry Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetryTa5d6ff"Tb4b4b4)
Tff7b72if Tb4b4b4(Tffa657isinstanceTb4b4b4(Te6edf3telemetryTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3telemetryTb4b4b4) Tff7b72or Tb4b4b4(
Tffa657isinstanceTb4b4b4(Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetry_streamTa5d6ff"Tb4b4b4)Tb4b4b4, Tffa657listTb4b4b4)
Tff7b72and Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(
Ta5d6ff"Ta5d6fftelemetry_streamTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Te6edf3has_telemetry Tff7b72= T79c0ff1
T8b949e# Also accept raw LXMF hex-style keys that may appear in stored JSON.
Tff7b72if Tff7b72not Te6edf3has_image Tff7b72and Tb4b4b4(Ta5d6ff"Ta5d6ff0x05Ta5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4)Tb4b4b4:
Te6edf3has_image Tff7b72= T79c0ff1
Tff7b72if Tff7b72not Te6edf3has_audio Tff7b72and Tb4b4b4(Ta5d6ff"Ta5d6ff0x06Ta5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4)Tb4b4b4:
Te6edf3has_audio Tff7b72= T79c0ff1
Tff7b72if Tff7b72not Te6edf3has_files Tff7b72and Tb4b4b4(Ta5d6ff"Ta5d6ff0x07Ta5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4)Tb4b4b4:
Te6edf3has_files Tff7b72= T79c0ff1
Tff7b72if Tff7b72not Te6edf3has_reaction Tff7b72and Tb4b4b4(Ta5d6ff"Ta5d6ff0x40Ta5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4)Tb4b4b4:
Te6edf3has_reaction Tff7b72= T79c0ff1
Tff7b72if Tff7b72not Te6edf3has_telemetry Tff7b72and Tb4b4b4(Ta5d6ff"Ta5d6ff0x08Ta5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4)Tb4b4b4:
Te6edf3has_telemetry Tff7b72= T79c0ff1
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4: Te6edf3has_imageTb4b4b4,
Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4: Te6edf3has_audioTb4b4b4,
Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4: Te6edf3has_filesTb4b4b4,
Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4: Te6edf3has_reactionTb4b4b4,
Ta5d6ff"Ta5d6ffhas_telemetryTa5d6ff"Tb4b4b4: Te6edf3has_telemetryTb4b4b4,
Tb4b4b4}
Tff7b72def Td2a8ffsynthesize_fields_from_attachment_flagsTb4b4b4(Te6edf3rowTb4b4b4: Tffa657dictTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
T8b949e"""Build minimal fields when full JSON was omitted from a list/thread query."""
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffaudio_modeTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffaudio_sizeTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffaudio_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6fffile_nameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffattachmentTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffile_sizeTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6fffile_bytesTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_telemetryTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6fftelemetryTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72return Te6edf3fields
Tff7b72def Td2a8fflxmf_sidebar_preview_for_conversation_latest_rowTb4b4b4(
Te6edf3rowTb4b4b4: Tffa657dictTb4b4b4,
Tff7b72*Tb4b4b4,
Te6edf3local_hashTb4b4b4: Tffa657strTb4b4b4,
Te6edf3peer_display_nameTb4b4b4: Tffa657strTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
T8b949e"""Single-line preview for conversation list APIs (reactions and some media have empty body).
Conversation list rows may omit full fields (to avoid loading multi-MB
attachment blobs). In that case SQL-derived flags such as has_image /
has_reaction are used instead.
"""
Te6edf3content Tff7b72= Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3content Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657strTb4b4b4(Te6edf3contentTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e# List queries may already truncate content. keep previews bounded.
Te6edf3text Tff7b72= Tffa657strTb4b4b4(Te6edf3contentTb4b4b4)
Te6edf3stripped Tff7b72= Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3strippedTb4b4b4) Tff7b72<Tff7b72= T79c0ff240Tb4b4b4:
Tff7b72return Te6edf3text Tff7b72if Tffa657lenTb4b4b4(Te6edf3textTb4b4b4) Tff7b72<Tff7b72= T79c0ff240 Tff7b72else Te6edf3strippedTb4b4b4[Tb4b4b4:T79c0ff237Tb4b4b4] Tff7b72+ Ta5d6ff"Ta5d6ff...Ta5d6ff"
Tff7b72return Te6edf3strippedTb4b4b4[Tb4b4b4:T79c0ff237Tb4b4b4] Tff7b72+ Ta5d6ff"Ta5d6ff...Ta5d6ff"
Te6edf3actor Tff7b72= Te6edf3_lxmf_sidebar_actor_labelTb4b4b4(
Te6edf3rowTb4b4b4,
Te6edf3local_hashTff7b72=Te6edf3local_hashTb4b4b4,
Te6edf3peer_display_nameTff7b72=Te6edf3peer_display_nameTb4b4b4,
Tb4b4b4)
Te6edf3incoming Tff7b72= Tffa657boolTb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3fields_raw Tff7b72= Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4)
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3fields_raw Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fields_rawTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
T8b949e# Never json.loads multi-MB attachment blobs for a sidebar line.
Tff7b72if Tffa657lenTb4b4b4(Te6edf3fields_rawTb4b4b4) Tff7b72> T79c0ff16384Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72elseTb4b4b4:
Te6edf3fields Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3fields_rawTb4b4b4) Tff7b72if Te6edf3fields_raw Tff7b72else Tb4b4b4{Tb4b4b4}
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3fields_rawTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Te6edf3fields_raw
Tff7b72except Tb4b4b4(Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3fieldsTb4b4b4:
Te6edf3emoji Tff7b72= Te6edf3_reaction_emoji_from_parsed_lxmf_fieldsTb4b4b4(Te6edf3fieldsTb4b4b4)
Tff7b72if Te6edf3emojiTb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff reacted Tffd700{Te6edf3emojiTffd700}Ta5d6ff"
Te6edf3telemetry Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetryTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3telemetryTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3loc Tff7b72= Te6edf3telemetryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflocationTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3locTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3locTb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou shared your locationTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff shared their locationTa5d6ff"
Te6edf3ts Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftelemetry_streamTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3tsTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3tsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a telemetry streamTa5d6ff"
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3telemetryTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3telemetryTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent telemetryTa5d6ff"
Te6edf3commands Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcommandsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3commandsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3cmd Tff7b72in Te6edf3commandsTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cmdTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Ta5d6ff"Ta5d6ff0x01Ta5d6ff" Tff7b72in Te6edf3cmdTb4b4b4:
Tff7b72if Te6edf3incomingTb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff requested your locationTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a location requestTa5d6ff"
Te6edf3image Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3imageTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3imageTb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent an imageTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent an imageTa5d6ff"
Te6edf3audio Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3audioTb4b4b4, Tffa657dictTb4b4b4) Tff7b72and Te6edf3audioTb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent a voice noteTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a voice noteTa5d6ff"
Te6edf3file_attachments Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3file_attachmentsTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3file_attachmentsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3n Tff7b72= Tffa657lenTb4b4b4(Te6edf3file_attachmentsTb4b4b4)
Tff7b72if Te6edf3n Tff7b72== T79c0ff1Tb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent a fileTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a fileTa5d6ff"
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Ta5d6ffYou sent Tffd700{Te6edf3nTffd700}Ta5d6ff filesTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent Tffd700{Te6edf3nTffd700}Ta5d6ff filesTa5d6ff"
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff reactedTa5d6ff"
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent an imageTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent an imageTa5d6ff"
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent a voice noteTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a voice noteTa5d6ff"
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3actor Tff7b72== Ta5d6ff"Ta5d6ffYouTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffYou sent a fileTa5d6ff"
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent a fileTa5d6ff"
Tff7b72if Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_telemetryTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6fffTa5d6ff"Tffd700{Te6edf3actorTffd700}Ta5d6ff sent telemetryTa5d6ff"
Tff7b72return Tffa657strTb4b4b4(Te6edf3content Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72def Td2a8fflxmf_message_solving_stampsTb4b4b4(
Te6edf3lxmf_messageTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4,
Te6edf3message_routerTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72if Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffincomingTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Tff7b72if Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffoutbound_ticketTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4) Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72False
Te6edf3stamp_cost Tff7b72= Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffstamp_costTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3needs_direct_stamp Tff7b72= Tb4b4b4(
Te6edf3stamp_cost Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffstampTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4) Tff7b72is Tff7b72None
Tb4b4b4)
Te6edf3desired_method Tff7b72= Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffdesired_methodTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3needs_propagation_stamp Tff7b72= Tb4b4b4(
Te6edf3desired_method Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Tff7b72and Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffdefer_propagation_stampTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)
Tff7b72and Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffpropagation_stampTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4) Tff7b72is Tff7b72None
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3needs_direct_stamp Tff7b72and Tff7b72not Te6edf3needs_propagation_stampTb4b4b4:
Tff7b72return Tff7b72False
Te6edf3pending_deferred Tff7b72= Tb4b4b4(
Tffa657getattrTb4b4b4(Te6edf3message_routerTb4b4b4, Ta5d6ff"Ta5d6ffpending_deferred_stampsTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3message_router
Tff7b72else Tff7b72None
Tb4b4b4)
Te6edf3message_id Tff7b72= Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffmessage_idTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Tb4b4b4(
Te6edf3pending_deferred Tff7b72is Tff7b72not Tff7b72None
Tff7b72and Te6edf3message_id Tff7b72is Tff7b72not Tff7b72None
Tff7b72and Te6edf3message_id Tff7b72in Te6edf3pending_deferred
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Te6edf3state Tff7b72= Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3pending_states Tff7b72= Tb4b4b4{Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffGENERATINGTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOUTBOUNDTb4b4b4}
Tff7b72if Te6edf3needs_direct_stampTb4b4b4:
Tff7b72if Tffa657getattrTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Ta5d6ff"Ta5d6ffdefer_stampTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3state Tff7b72in Te6edf3pending_statesTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elif Te6edf3state Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffGENERATINGTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3needs_propagation_stamp Tff7b72and Te6edf3state Tff7b72in Te6edf3pending_statesTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False
Tff7b72def Td2a8ffconvert_lxmf_message_to_dictTb4b4b4(
Te6edf3lxmf_messageTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4,
Te6edf3include_attachmentsTb4b4b4: Tffa657bool Tff7b72= Tff7b72TrueTb4b4b4,
Te6edf3reticulumTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3message_routerTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3state_overrideTb4b4b4: Tffa657str Tff7b72| Tff7b72None Tff7b72= Tff7b72NoneTb4b4b4,
Te6edf3method_overrideTb4b4b4: Tffa657str Tff7b72| Tff7b72None Tff7b72= Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4:
T8b949e# handle fields
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3message_fields Tff7b72= Te6edf3lxmf_messageTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Te6edf3is_reaction Tff7b72= Tff7b72False
Te6edf3reaction_to Tff7b72= Tff7b72None
Te6edf3reaction_emoji Tff7b72= Tff7b72None
Te6edf3reaction_sender Tff7b72= Tff7b72None
Tff7b72for Te6edf3field_type Tff7b72in Te6edf3message_fieldsTb4b4b4:
Te6edf3value Tff7b72= Te6edf3message_fieldsTb4b4b4[Te6edf3field_typeTb4b4b4]
T8b949e# handle file attachments field
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTS Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3file_attachments Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3file_attachment Tff7b72in Te6edf3valueTb4b4b4:
Tff7b72if Tb4b4b4(
Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3file_attachmentTb4b4b4, Tb4b4b4(Tffa657listTb4b4b4, Tffa657tupleTb4b4b4)Tb4b4b4)
Tff7b72or Tffa657lenTb4b4b4(Te6edf3file_attachmentTb4b4b4) Tff7b72< T79c0ff2
Tb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3file_name Tff7b72= Te6edf3file_attachmentTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3file_data Tff7b72= Te6edf3file_attachmentTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3file_dataTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3file_bytes Tff7b72= Tff7b72None
Tff7b72if Te6edf3include_attachmentsTb4b4b4:
Te6edf3file_bytes Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3file_dataTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(
Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3file_attachmentsTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fffile_nameTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3file_nameTb4b4b4) Tff7b72if Te6edf3file_name Tff7b72else Ta5d6ff"Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffile_sizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3file_dataTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fffile_bytesTa5d6ff"Tb4b4b4: Te6edf3file_bytesTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6fffile_attachmentsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3file_attachments
T8b949e# handle image field
Tff7b72if Tb4b4b4(
Te6edf3field_type Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tb4b4b4(Tffa657listTb4b4b4, Tffa657tupleTb4b4b4)Tb4b4b4)
Tff7b72and Tffa657lenTb4b4b4(Te6edf3valueTb4b4b4) Tff7b72>Tff7b72= T79c0ff2
Tb4b4b4)Tb4b4b4:
Te6edf3image_type Tff7b72= Te6edf3valueTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3image_data Tff7b72= Te6edf3valueTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3image_dataTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3image_bytes Tff7b72= Tff7b72None
Tff7b72if Te6edf3include_attachmentsTb4b4b4:
Te6edf3image_bytes Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3image_dataTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Te6edf3image_typeTb4b4b4,
Ta5d6ff"Ta5d6ffimage_sizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3image_dataTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4: Te6edf3image_bytesTb4b4b4,
Tb4b4b4}
T8b949e# handle audio field
Tff7b72if Tb4b4b4(
Te6edf3field_type Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tb4b4b4(Tffa657listTb4b4b4, Tffa657tupleTb4b4b4)Tb4b4b4)
Tff7b72and Tffa657lenTb4b4b4(Te6edf3valueTb4b4b4) Tff7b72>Tff7b72= T79c0ff2
Tb4b4b4)Tb4b4b4:
Te6edf3audio_mode Tff7b72= Te6edf3valueTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3audio_data Tff7b72= Te6edf3valueTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3audio_dataTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3audio_bytes Tff7b72= Tff7b72None
Tff7b72if Te6edf3include_attachmentsTb4b4b4:
Te6edf3audio_bytes Tff7b72= Te6edf3base64Tff7b72.Td2a8ffb64encodeTb4b4b4(Te6edf3audio_dataTb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffaudio_modeTa5d6ff"Tb4b4b4: Te6edf3audio_modeTb4b4b4,
Ta5d6ff"Ta5d6ffaudio_sizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3audio_dataTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffaudio_bytesTa5d6ff"Tb4b4b4: Te6edf3audio_bytesTb4b4b4,
Tb4b4b4}
T8b949e# handle telemetry field
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffFIELD_TELEMETRYTb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6fftelemetryTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3TelemeterTff7b72.Td2a8fffrom_packedTb4b4b4(Te6edf3valueTb4b4b4)
T8b949e# handle commands field
Tff7b72if Te6edf3field_type Tff7b72in Tb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_COMMANDSTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4:
Te6edf3processed_commands Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3cmd Tff7b72in Te6edf3valueTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cmdTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3new_cmd Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3cmdTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3kTb4b4b4, Tffa657intTb4b4b4)Tb4b4b4:
Te6edf3new_cmdTb4b4b4[Ta5d6fffTa5d6ff"Ta5d6ff0xTffd700{Te6edf3kTffd700:Ta5d6ff02xTffd700}Ta5d6ff"Tb4b4b4] Tff7b72= Te6edf3v
Tff7b72elseTb4b4b4:
Te6edf3new_cmdTb4b4b4[Tffa657strTb4b4b4(Te6edf3kTb4b4b4)Tb4b4b4] Tff7b72= Te6edf3v
Te6edf3processed_commandsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3new_cmdTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3processed_commandsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3cmdTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3new_cmd Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3valueTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3kTb4b4b4, Tffa657intTb4b4b4)Tb4b4b4:
Te6edf3new_cmdTb4b4b4[Ta5d6fffTa5d6ff"Ta5d6ff0xTffd700{Te6edf3kTffd700:Ta5d6ff02xTffd700}Ta5d6ff"Tb4b4b4] Tff7b72= Te6edf3v
Tff7b72elseTb4b4b4:
Te6edf3new_cmdTb4b4b4[Tffa657strTb4b4b4(Te6edf3kTb4b4b4)Tb4b4b4] Tff7b72= Te6edf3v
Te6edf3processed_commandsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3new_cmdTb4b4b4)
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffcommandsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3processed_commands
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3FIELD_REPLY_TOTb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffreply_toTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3valueTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72else Te6edf3value
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3FIELD_REPLY_QUOTETb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffreply_quoted_contentTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4(
Te6edf3valueTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657bytesTb4b4b4)
Tff7b72else Te6edf3value
Tb4b4b4)
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3FIELD_REACTION Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3parsed_reaction Tff7b72= Te6edf3parse_lxmf_reaction_field_dictTb4b4b4(
Te6edf3valueTb4b4b4,
Te6edf3lxmf_messageTff7b72.Td2a8ffsource_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3parsed_reactionTb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffreactionTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4: Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffreaction_contentTa5d6ff"Tb4b4b4: Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4]Tb4b4b4,
Tb4b4b4}
Te6edf3is_reaction Tff7b72= Tff7b72True
Te6edf3reaction_to Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4]
Te6edf3reaction_emoji Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4]
Te6edf3reaction_sender Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4]
Tff7b72if Te6edf3field_type Tff7b72== Te6edf3LXMF_APP_EXTENSIONS_FIELD Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3valueTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffapp_extensionsTa5d6ff"Tb4b4b4] Tff7b72= Tffa657dictTb4b4b4(Te6edf3valueTb4b4b4)
T8b949e# convert 0.0-1.0 progress to 0.00-100 percentage
Te6edf3progress_percentage Tff7b72= Tffa657roundTb4b4b4(Te6edf3lxmf_messageTff7b72.Td2a8ffprogress Tff7b72* T79c0ff100Tb4b4b4, T79c0ff2Tb4b4b4)
T8b949e# get rssi
Te6edf3rssi Tff7b72= Te6edf3lxmf_messageTff7b72.Td2a8ffrssi
Tff7b72if Te6edf3rssi Tff7b72is Tff7b72None Tff7b72and Te6edf3reticulumTb4b4b4:
Te6edf3rssi Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_rssiTb4b4b4(Te6edf3lxmf_messageTff7b72.Td2a8ffhashTb4b4b4)
T8b949e# get snr
Te6edf3snr Tff7b72= Te6edf3lxmf_messageTff7b72.Td2a8ffsnr
Tff7b72if Te6edf3snr Tff7b72is Tff7b72None Tff7b72and Te6edf3reticulumTb4b4b4:
Te6edf3snr Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_snrTb4b4b4(Te6edf3lxmf_messageTff7b72.Td2a8ffhashTb4b4b4)
T8b949e# get quality
Te6edf3quality Tff7b72= Te6edf3lxmf_messageTff7b72.Td2a8ffq
Tff7b72if Te6edf3quality Tff7b72is Tff7b72None Tff7b72and Te6edf3reticulumTb4b4b4:
Te6edf3quality Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_qTb4b4b4(Te6edf3lxmf_messageTff7b72.Td2a8ffhashTb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_reactionTb4b4b4:
Te6edf3parsed_reaction Tff7b72= Te6edf3extract_reaction_from_lxmf_fieldsTb4b4b4(
Te6edf3message_fieldsTb4b4b4,
Te6edf3source_hash_hexTff7b72=Te6edf3lxmf_messageTff7b72.Td2a8ffsource_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3parsed_fieldsTff7b72=Te6edf3fieldsTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3parsed_reactionTb4b4b4:
Te6edf3is_reaction Tff7b72= Tff7b72True
Te6edf3reaction_to Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4]
Te6edf3reaction_emoji Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4]
Te6edf3reaction_sender Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4]
Te6edf3reply_to_hash Tff7b72= Tff7b72None
Tff7b72if Te6edf3FIELD_REPLY_TO Tff7b72in Te6edf3message_fieldsTb4b4b4:
Te6edf3val Tff7b72= Te6edf3message_fieldsTb4b4b4[Te6edf3FIELD_REPLY_TOTb4b4b4]
Te6edf3reply_to_hash Tff7b72= Te6edf3valTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3valTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72else Te6edf3val
Tff7b72elif Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreply_toTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3reply_to_hash Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreply_toTa5d6ff"Tb4b4b4)
Te6edf3content Tff7b72= Tb4b4b4(
Te6edf3lxmf_messageTff7b72.Td2a8ffcontentTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffcontent
Tff7b72else Ta5d6ff"Ta5d6ff"
Tb4b4b4)
T8b949e# auto-detect reply from content if not present
Tff7b72if Tff7b72not Te6edf3reply_to_hash Tff7b72and Te6edf3content Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3contentTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72import T7ee787re
Te6edf3match Tff7b72= Te6edf3reTff7b72.Td2a8ffsearchTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff^> ([a-fA-F0-9]Tffd700{32}Ta5d6ff)Ta5d6ff\Ta5d6ffs*Ta5d6ff\Ta5d6ffn?Ta5d6ff"Tb4b4b4, Te6edf3contentTb4b4b4)
Tff7b72if Te6edf3matchTb4b4b4:
Te6edf3reply_to_hash Tff7b72= Te6edf3matchTff7b72.Td2a8ffgroupTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3out Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8ffsource_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8ffdestination_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8ffincomingTb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Te6edf3state_override
Tff7b72if Te6edf3state_override Tff7b72is Tff7b72not Tff7b72None
Tff7b72else Te6edf3convert_lxmf_state_to_stringTb4b4b4(Te6edf3lxmf_messageTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4: Te6edf3progress_percentageTb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Te6edf3method_override
Tff7b72if Te6edf3method_override Tff7b72is Tff7b72not Tff7b72None
Tff7b72else Te6edf3convert_lxmf_method_to_stringTb4b4b4(Te6edf3lxmf_messageTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4: Tffa657getattrTb4b4b4(
Te6edf3lxmf_messageTb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4,
Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4, T8b949e# attribute may not exist yet
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8fftitleTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8fftitle
Tff7b72else Ta5d6ff"Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Te6edf3contentTb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4: Te6edf3fieldsTb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3lxmf_messageTff7b72.Td2a8fftimestampTb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Te6edf3rssiTb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: Te6edf3snrTb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: Te6edf3qualityTb4b4b4,
Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4: Te6edf3reply_to_hashTb4b4b4,
Ta5d6ff"Ta5d6ffis_reactionTa5d6ff"Tb4b4b4: Te6edf3is_reactionTb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3is_reactionTb4b4b4:
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_to
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_emoji
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_sender
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffsolving_stampsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3lxmf_message_solving_stampsTb4b4b4(Te6edf3lxmf_messageTb4b4b4, Te6edf3message_routerTb4b4b4)
Tff7b72return Te6edf3out
Tff7b72def Td2a8ffis_lxmf_outbound_progress_terminalTb4b4b4(Te6edf3lxmf_messageTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""True when MeshChat should stop polling outbound progress.
Opportunistic or direct SENT is not terminal. Without an RNS delivery proof
the message stays SENT while LXMF retries, and only later becomes
DELIVERED, FAILED, or CANCELLED. Propagated SENT means parked on a node.
FAILED with try_propagation_on_fail still pending is also non-terminal.
REJECTED is terminal (peer refused the message).
"""
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffREJECTEDTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Tb4b4b4(
Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENT
Tff7b72and Te6edf3lxmf_messageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffCANCELLEDTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Tb4b4b4(
Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILED
Tff7b72and Tffa657getattrTb4b4b4(
Te6edf3lxmf_messageTb4b4b4,
Ta5d6ff"Ta5d6fftry_propagation_on_failTa5d6ff"Tb4b4b4,
Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72not Tff7b72True
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False
Tff7b72def Td2a8ffconvert_lxmf_state_to_stringTb4b4b4(Te6edf3lxmf_messageTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4)Tb4b4b4:
T8b949e# convert state to string
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffunknownTa5d6ff"
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffGENERATINGTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffgeneratingTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOUTBOUNDTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffoutboundTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENDINGTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffsendingTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffsentTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffdeliveredTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffREJECTEDTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffrejectedTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffCANCELLEDTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6ffcancelledTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILEDTb4b4b4:
Te6edf3lxmf_message_state Tff7b72= Ta5d6ff"Ta5d6fffailedTa5d6ff"
Tff7b72return Te6edf3lxmf_message_state
Tff7b72def Td2a8ffconvert_lxmf_method_to_stringTb4b4b4(Te6edf3lxmf_messageTb4b4b4: Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4)Tb4b4b4:
T8b949e# convert method to string
Te6edf3lxmf_message_method Tff7b72= Ta5d6ff"Ta5d6ffunknownTa5d6ff"
Tff7b72if Te6edf3lxmf_messageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4:
Te6edf3lxmf_message_method Tff7b72= Ta5d6ff"Ta5d6ffopportunisticTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECTTb4b4b4:
Te6edf3lxmf_message_method Tff7b72= Ta5d6ff"Ta5d6ffdirectTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATEDTb4b4b4:
Te6edf3lxmf_message_method Tff7b72= Ta5d6ff"Ta5d6ffpropagatedTa5d6ff"
Tff7b72elif Te6edf3lxmf_messageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPAPERTb4b4b4:
Te6edf3lxmf_message_method Tff7b72= Ta5d6ff"Ta5d6ffpaperTa5d6ff"
Tff7b72return Te6edf3lxmf_message_method
Tff7b72def Td2a8ffconvert_db_lxmf_message_to_dictTb4b4b4(
Te6edf3db_lxmf_messageTb4b4b4,
Te6edf3include_attachmentsTb4b4b4: Tffa657bool Tff7b72= Tff7b72FalseTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3fields_raw Tff7b72= Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3fields_raw Tff7b72is Tff7b72None Tff7b72or Te6edf3fields_raw Tff7b72== Ta5d6ff"Ta5d6ff"Tb4b4b4:
Te6edf3fields_raw Tff7b72= Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffields_metaTa5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fields_rawTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Te6edf3fields_raw
Tff7b72elif Te6edf3fields_rawTb4b4b4:
Te6edf3fields Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3fields_rawTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72except Tb4b4b4(Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Tff7b72not Te6edf3fields Tff7b72and Tb4b4b4(
Te6edf3_row_flag_trueTb4b4b4(
Te6edf3db_lxmf_messageTb4b4b4,
Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_telemetryTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Te6edf3synthesize_fields_from_attachment_flagsTb4b4b4(Te6edf3db_lxmf_messageTb4b4b4)
Te6edf3is_reaction Tff7b72= Tff7b72False
Te6edf3reaction_to Tff7b72= Tff7b72None
Te6edf3reaction_emoji Tff7b72= Tff7b72None
Te6edf3reaction_sender Tff7b72= Tff7b72None
Te6edf3source_hash Tff7b72= Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"
Te6edf3parsed_reaction Tff7b72= Te6edf3extract_reaction_from_lxmf_fieldsTb4b4b4(
Te6edf3fieldsTb4b4b4,
Te6edf3source_hash_hexTff7b72=Te6edf3source_hashTb4b4b4,
Te6edf3parsed_fieldsTff7b72=Te6edf3fieldsTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3parsed_reactionTb4b4b4:
Te6edf3is_reaction Tff7b72= Tff7b72True
Te6edf3reaction_to Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4]
Te6edf3reaction_emoji Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4]
Te6edf3reaction_sender Tff7b72= Te6edf3parsed_reactionTb4b4b4[Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4] Tff7b72or Te6edf3source_hash
T8b949e# normalize commands if present
Tff7b72if Ta5d6ff"Ta5d6ffcommandsTa5d6ff" Tff7b72in Te6edf3fieldsTb4b4b4:
Te6edf3cmds Tff7b72= Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffcommandsTa5d6ff"Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cmdsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3new_cmds Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3cmd Tff7b72in Te6edf3cmdsTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cmdTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3new_cmd Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3cmdTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e# normalize key to 0xXX format if it's a number string
Tff7b72tryTb4b4b4:
Te6edf3ki Tff7b72= Tff7b72None
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3kTb4b4b4, Tffa657intTb4b4b4)Tb4b4b4:
Te6edf3ki Tff7b72= Te6edf3k
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3kTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3kTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff0xTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3ki Tff7b72= Tffa657intTb4b4b4(Te6edf3kTb4b4b4, T79c0ff16Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3ki Tff7b72= Tffa657intTb4b4b4(Te6edf3kTb4b4b4)
Tff7b72if Te6edf3ki Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3new_cmdTb4b4b4[Ta5d6fffTa5d6ff"Ta5d6ff0xTffd700{Te6edf3kiTffd700:Ta5d6ff02xTffd700}Ta5d6ff"Tb4b4b4] Tff7b72= Te6edf3v
Tff7b72elseTb4b4b4:
Te6edf3new_cmdTb4b4b4[Tffa657strTb4b4b4(Te6edf3kTb4b4b4)Tb4b4b4] Tff7b72= Te6edf3v
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Te6edf3new_cmdTb4b4b4[Tffa657strTb4b4b4(Te6edf3kTb4b4b4)Tb4b4b4] Tff7b72= Te6edf3v
Te6edf3new_cmdsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3new_cmdTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3new_cmdsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3cmdTb4b4b4)
Te6edf3fieldsTb4b4b4[Ta5d6ff"Ta5d6ffcommandsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3new_cmds
T8b949e# strip attachments if requested
Tff7b72if Tff7b72not Te6edf3include_attachmentsTb4b4b4:
Te6edf3fields Tff7b72= Te6edf3lxmf_fields_without_attachment_bytesTb4b4b4(Te6edf3fieldsTb4b4b4)
T8b949e# ensure created_at and updated_at have Z suffix for UTC if they don't have a timezone
Te6edf3created_at Tff7b72= Tffa657strTb4b4b4(Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffcreated_atTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3created_at Tff7b72and Ta5d6ff"Ta5d6ff+Ta5d6ff" Tff7b72not Tff7b72in Te6edf3created_at Tff7b72and Ta5d6ff"Ta5d6ffZTa5d6ff" Tff7b72not Tff7b72in Te6edf3created_atTb4b4b4:
Te6edf3created_at Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ffZTa5d6ff"
Te6edf3updated_at Tff7b72= Tffa657strTb4b4b4(Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3updated_at Tff7b72and Ta5d6ff"Ta5d6ff+Ta5d6ff" Tff7b72not Tff7b72in Te6edf3updated_at Tff7b72and Ta5d6ff"Ta5d6ffZTa5d6ff" Tff7b72not Tff7b72in Te6edf3updated_atTb4b4b4:
Te6edf3updated_at Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ffZTa5d6ff"
Te6edf3out Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ffunknownTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4: Te6edf3fieldsTb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3db_lxmf_messageTb4b4b4[Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffattachments_strippedTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffattachments_strippedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpath_hops_at_sendTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpath_hops_at_sendTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpath_interface_at_sendTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpath_interface_at_sendTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpath_finding_measureTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpath_finding_measureTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpath_row_hash_hexTa5d6ff"Tb4b4b4: Te6edf3db_lxmf_messageTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffpath_row_hash_hexTa5d6ff"Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcreated_atTa5d6ff"Tb4b4b4: Te6edf3created_atTb4b4b4,
Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4: Te6edf3updated_atTb4b4b4,
Ta5d6ff"Ta5d6ffis_reactionTa5d6ff"Tb4b4b4: Te6edf3is_reactionTb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3is_reactionTb4b4b4:
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_toTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_to
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_emojiTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_emoji
Te6edf3outTb4b4b4[Ta5d6ff"Ta5d6ffreaction_senderTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3reaction_sender
Tff7b72return Te6edf3out
Tff7b72def Td2a8ffcompute_lxmf_conversation_unread_from_latest_rowTb4b4b4(Te6edf3rowTb4b4b4, Tff7b72*Tb4b4b4, Te6edf3require_user_facingTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e"""Return whether the conversation row should appear as unread.
Uses lxmf_conversation_read_state.last_read_at only. The latest message
must be incoming. outbound-only threads are not unread (matches
filter_unread in MessageHandler.get_conversations).
When require_user_facing is True, the row's latest message must also be
user-facing (i.e. not a bare reaction / telemetry / icon-only payload).
Used by the notification bell so silent system messages do not raise the
unread badge.
"""
Tff7b72from T7ee787datetime Tff7b72import Te6edf3UTCTb4b4b4, Te6edf3datetime
Tff7b72if Tff7b72not Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Tff7b72if Te6edf3require_user_facingTb4b4b4:
Tff7b72if Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Te6edf3is_user_facing_lxmf_payloadTb4b4b4(
Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Tff7b72elif Te6edf3_row_flag_trueTb4b4b4(Te6edf3rowTb4b4b4, Ta5d6ff"Ta5d6ffhas_reactionTa5d6ff"Tb4b4b4) Tff7b72and Tff7b72not Tb4b4b4(
Tb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4) Tff7b72and Tffa657strTb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72or Tb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4) Tff7b72and Tffa657strTb4b4b4(Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72or Te6edf3_row_flag_trueTb4b4b4(
Te6edf3rowTb4b4b4,
Ta5d6ff"Ta5d6ffhas_imageTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_audioTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_filesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhas_attachmentsTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3last_read_at_raw Tff7b72= Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflast_read_atTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3last_read_at_rawTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72tryTb4b4b4:
Te6edf3last_read_at Tff7b72= Te6edf3datetimeTff7b72.Td2a8fffromisoformatTb4b4b4(Tffa657strTb4b4b4(Te6edf3last_read_at_rawTb4b4b4)Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72if Te6edf3last_read_atTff7b72.Td2a8fftzinfo Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3last_read_at Tff7b72= Te6edf3last_read_atTff7b72.Td2a8ffreplaceTb4b4b4(Te6edf3tzinfoTff7b72=Te6edf3UTCTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72return Tffa657floatTb4b4b4(Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4]Tb4b4b4) Tff7b72> Te6edf3last_read_atTff7b72.Td2a8fftimestampTb4b4b4(Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4, Tf85149KeyErrorTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────